﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Evoucher.Business.PaymentGateways;
using Evoucher.Business.Models;
using Mani.Common;
using System.Web.Security;
using System.IO;
using System.Text;
using Evoucher.Business.Logging;

public partial class Payment : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        dvCurvy.Visible = false;

        MembershipUser user = Membership.GetUser();
        string username = "";
        if (user != null)
            username = user.UserName;

        if (Session["transaction"] == null)
        {
            lblMessage.Text = " پروسه کاری شما منقضی شده است لطفا مجددا تلاش کنید چنانچه پولی از حساب شما کم شده باشد پول ظرف مدت حداکثر 2 ساعت به حساب شما باز خواهد گشت";
            Logger.LogEvent("Session[transaction] was null!", username);
            return;
        }

        Transaction temp = (Transaction)Session["transaction"];
        IVoucherRepository repo = new VoucherRepository();
        Transaction t = repo.GetTransactionById(temp.Id);
        t.PaymentGatewayReference.Load();

        String RefNum = Request.Form["RefNum"];
        String ResNum = Request.Form["ResNum"];
        String Status = Request.Form["State"];

        // Check if parameters are available
        if (String.IsNullOrEmpty(RefNum) || String.IsNullOrEmpty(Status) || String.IsNullOrEmpty(ResNum) )
        {
            lblMessage.Text = "خطای امنیتی! لطفا مجددا تلاش کنید چنانچه پولی از حساب شما کم شده باشد پول ظرف مدت حداکثر 2 ساعت به حساب شما باز خواهد گشت";
            
            object[] args = new object[3] { RefNum, Status, ResNum };
            Logger.LogEvent(String.Format("Security Error in parameters: Refnum-{0}; Status-{1}; ResNum-{2};", args), username);

            t.TransactionState = repo.GetTransactionStateById((int)TransactionStatus.ParamSecurityErrors);

            if (!String.IsNullOrEmpty(RefNum))
                t.ReferenceNumber = RefNum;

            repo.persist();

            return;
        }

        // IMPORTANT::Check if Reference Number is not duplicate
        Transaction t1 = repo.GetTransactionByRefNum(RefNum);
        if (t1 != null)
        {
            lblMessage.Text = "خطای امنیتی! لطفا مجددا تلاش کنید چنانچه پولی از حساب شما کم شده باشد پول ظرف مدت حداکثر 2 ساعت به حساب شما باز خواهد گشت";

            object[] args = new object[3] { RefNum, Status, ResNum };
            Logger.LogEvent(String.Format("Duplicate Reference Number: Refnum-{0}; Status-{1}; ResNum-{2};", args), username);
        }


        lblRefrenceNumber.Text = RefNum;

        t.PaymentGatewayReference.Load();
        IPaymentGateway pgw = PaymentGatewayFactory.CreateGateway(t.PaymentGateway.Id);
        double amount = pgw.VerifyTransaction(RefNum, t.PaymentGateway.MerchantId);

        if (amount != t.Amount.Value)
        {
            Logger.LogEvent(String.Format("Error in VerifyTransaction. actual amount should be {0} while bank response is {1}.", t.Amount.Value, amount), username);
            lblMessage.Text = "خطا در تایید تراکنش از سمت بانک! مبلغ کسر شده ظرف مدت حداکثر 2 ساعت به حساب شما بازگردانده خواهد شد";
            t.ReferenceNumber = RefNum;
            t.TransactionState = repo.GetTransactionStateById((int)TransactionStatus.AmountVerifyError);
            repo.persist();
            return;
        }

        EmailAndShowVouchers(RefNum);
    }

    /* It's not usefull because it's coming from https and doesn't have referrer
     * referrer is always null in this case.
     * 
    private bool VerifyReferrerUrl(string paymentGatewayUrl)
    {
        return (Request.UrlReferrer.OriginalString.ToLower() == paymentGatewayUrl.ToLower());
    }
     * 
     * */

    private void EmailAndShowVouchers(string RefNum)
    {
        dvCurvy.Visible = true;

        IVoucherRepository repo = new VoucherRepository();
        Transaction temp = (Transaction)Session["transaction"];

        Transaction t = repo.GetTransactionById(temp.Id);
        t.Vouchers.Load();
        List<Voucher> vouchers = t.Vouchers.ToList<Voucher>();

        t.TransactionState = repo.GetTransactionStateById((int)TransactionStatus.Success);
        t.ReferenceNumber = RefNum;
        

        StreamReader sreader = new StreamReader(Server.MapPath("~") + Resources.global.EmailsFilesRoot + "Invoice.htm");
        string content = sreader.ReadToEnd();
        
        MembershipUser user = Membership.GetUser();
        String username = "";
        if (user != null)
        {
            username = user.UserName;
            aspnet_Users u = repo.GetUserByName(user.UserName);
            t.aspnet_Users = u;
        }
        StringBuilder sb = new StringBuilder();
        int i = 3;
        string tdWithColor, tdWithoutColor;
        tdWithColor="<td  style='background:#eee;text-align:center;font:bold 12px tahoma;width:25%' >";
        tdWithoutColor="<td  style='text-align:center;font:bold 12px tahoma;width:25%' >";

        foreach (var v in vouchers)
        {
            
            v.VoucherTypeReference.Load();
            v.VoucherState = repo.GetVoucherStateById((int)VoucherStates.Sold);
            v.LastUpdateDate = DateTime.Now.Date;
            if (i % 2 == 0)
            {
                sb.Append("<tr>");
                sb.Append(tdWithColor);
                sb.Append(v.Serial);
                sb.Append("</td>");
                sb.Append(tdWithColor);
                sb.Append(CommaSeparator(v.PlainPin.ToString()));
                sb.Append("</td>");
                sb.Append(tdWithColor);
                sb.Append(v.VoucherType.Price);
                sb.Append("</td></tr>");
            }
            else
            { 
                sb.Append("<tr>");
                sb.Append(tdWithoutColor);
                sb.Append(v.Serial);
                sb.Append("</td>");
                sb.Append(tdWithoutColor);
                sb.Append(CommaSeparator(v.PlainPin.ToString()));
                sb.Append("</td>");
                sb.Append(tdWithoutColor);
                sb.Append(v.VoucherType.Price);
                sb.Append("</td>");
                sb.Append(tdWithoutColor);
                sb.Append(DateTime.Today.ToJalali());
                sb.Append("</td></tr>");

            }
            i++;

        }
        content = content.Replace("{Invoice}", sb.ToString());
        lgrid.Text = sb.ToString();
        repo.persist();

        Logger.LogEvent(String.Format("transaction for refNum {0} successfully done!", RefNum), username);

        try {
            SendEmail.EmailActivation(t.Email, content, Resources.global.InvoicTitle, Resources.global.SMTP, Resources.global.EmailPass, Resources.global.EmailAddress);
        }
        catch (Exception ex) {
            Logger.LogEvent(String.Format("Sending email failed for refNum {0}. reason: {1} ", RefNum, ex.ToString()), username);
        }

        sreader.Close();
        sreader.Dispose();
    }

    private string CommaSeparator(string str)
    {
        if (str.Length % 4 != 0)
            return str;

        string output = str;

        for (int i = 4; i < str.Length - 1; i = i + 4)
            output.Insert(i - 1, ",");

        return output;
    }
}